package org.liaohailong.victor;

import org.junit.Test;

import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest3 {


    @Test
    public void convert() {
//        String s = "PAYPALISHIRING";
//        int numRows = 3;
//        String s = "PAYPALISHIRING";
//        int numRows = 4;
//        String s = "A";
//        int numRows = 1;
        String s = "PAYPALISHIRING";
        int numRows = 9;
        String convert = new Daily().convert(s, numRows);
        log("convert = " + convert);
    }

    @Test
    public void findMedianSortedArrays() {
//        int[] nums1 = {1, 2, 3, 4};
//        int[] nums2 = {5, 6, 7, 8};
//        double median = new Daily().findMedianSortedArrays(nums1, nums2);
//        log("median = " + median);

        Daily daily = new Daily();

//        int[] nums1 = {4};
//        int[] nums2 = {-3, -2, -1, 0};
        int[] nums1 = {};
        int[] nums2 = {1};
        for (int k = 1; k <= nums1.length + nums2.length; k++) {
            int min = daily.getMin(nums1, nums2, k);
            log("k = " + k + ", min = " + min);
        }
    }


    @Test
    public void isPalindrome() {
        int x = 1120211;
        boolean palindrome = new Daily().isPalindrome(x);
        log("x = " + x + ", palindrome = " + palindrome);
    }

    @Test
    public void maxArea() {
        int[] height = {1, 8, 6, 2, 5, 4, 8, 3, 7}; // 49
//        int[] height = {1, 1}; // 49
        int i = new Daily().maxArea(height);
        log("i = " + i);
    }

    @Test
    public void intToRoman() {
        int num1 = 3; // III
        int num2 = 4; // IV
        int num3 = 9; // IX
        int num4 = 58; // LVIII
        int num5 = 1994; // MCMXCIV

        int[] arr = {num1, num2, num3, num4, num5};
        for (int num : arr) {
            String s = new Daily().intToRoman(num);
            log("num = " + num + ", s = " + s);
        }

    }

    @Test
    public void threeSumClosest() {
//        int[] nums = {-1, 2, 1, 4};
//        int target = 1;

//        int[] nums = {0,1,2};
//        int target = 0;

        int[] nums = {-1, 0, 1, 1, 55};
        int target = 3; // 2

        int total = new Daily().threeSumClosest(nums, target);
        log("total = " + total);
    }

    @Test
    public void threeSum() {
        int[] nums = {-2, 0, 1, 1, 2};
        List<List<Integer>> list = new Daily().threeSum(nums);
        log("list = " + list);
    }

    @Test
    public void fourSum() {
//        int[] nums  = {1,0,-1,0,-2,2};
//        int target = 0; // [[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]
//        int[] nums  = {0,0,0,0};
//        int target = 0; // [[0,0,0,0]]
        int[] nums = {-3, -1, 0, 2, 4, 5};
        int target = 2; // [[-3,-1,2,4]]

//        int[] nums = {2,2,2,2,2};
//        int target = 8; // [[2,2,2,2]]
        List<List<Integer>> list = new Daily().fourSum(nums, target);
        log("list = " + list);
    }

    @Test
    public void nextPermutation() {
        LinkedList<int[]> list = new LinkedList<>();
//        list.add(new int[]{1,2,3});
        list.add(new int[]{3, 2, 1});
//        list.add(new int[]{1,1,5});
//        list.add(new int[]{1,3,2});
//        list.add(new int[]{2,3,1});
//        list.add(new int[]{1,3,2});
        list.add(new int[]{1, 5, 8, 4, 7, 6, 5, 3, 1});


        Daily daily = new Daily();
        for (int[] nums : list) {
            log("before: " + Arrays.toString(nums));
            daily.nextPermutation(nums);
            log("after: " + Arrays.toString(nums));
        }
    }

    @Test
    public void combinationSum() {
        Daily daily = new Daily();

        int[] candidates = {2, 3, 5};
        int target = 8;
        List<List<Integer>> lists = daily.combinationSum(candidates, target);
        log(lists.toString());
    }

    @Test
    public void combinationSum2() {
        Daily daily = new Daily();

        int[] candidates = {1, 2, 7, 6, 1, 5};
        int target = 8;
        List<List<Integer>> lists = daily.combinationSum2(candidates, target);
        log(lists.toString());
    }

    @Test
    public void multiply() {
        Daily daily = new Daily();

        String num1 = "123";
        String num2 = "456"; // 56088
        String multiply = daily.multiply(num1, num2);
        log("multiply = " + multiply);
    }

    @Test
    public void permuteUnique() {
        Daily daily = new Daily();

//        int[] nums = {1, 2, 3};
        int[] nums = {1, 1, 2};
        List<List<Integer>> lists = daily.permuteUnique(nums);
        log(lists.toString());
    }

    @Test
    public void spiralOrder() {
        Daily daily = new Daily();

//        输入：matrix = [[1,2,3],[4,5,6],[7,8,9]]
//        输出：[1,2,3,6,9,8,7,4,5]
        int[][] matrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

//        输入：matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
//        输出：[1,2,3,4,8,12,11,10,9,5,6,7]
//        int[][] matrix = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};

//        int[][] matrix = {{3}, {2}};
        List<Integer> list = daily.spiralOrder(matrix);
        log(list.toString());
    }

    @Test
    public void insert() {
        Daily daily = new Daily();

//        输入：intervals = [[1,3],[6,9]], newInterval = [2,5]
//        输出：[[1,5],[6,9]]
//        int[][] intervals = {{1,3},{6,9}};
//        int[] newInterval = {2,5};

//        输入：intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
//        输出：[[1,2],[3,10],[12,16]]
//        解释：这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10]重叠。
        int[][] intervals = {{1, 2}, {3, 5}, {6, 7}, {8, 10}, {12, 16}};
        int[] newInterval = {4, 8};


//        输入：intervals = [], newInterval = [5,7]
//        输出：[[5,7]]
//        int[][] intervals = {};
//        int[] newInterval = {5,7};

//        输入：intervals = [[1,5]], newInterval = [2,3]
//        输出：[[1,5]]
//        int[][] intervals = {{1,5}};
//        int[] newInterval = {2,3};

//        输入：intervals = [[1,5]], newInterval = [2,7]
//        输出：[[1,7]]
//        int[][] intervals = {{1,5}};
//        int[] newInterval = {2,7};

//        int[][] intervals = {{1,5}};
//        int[] newInterval = {6,8};

//        int[][] intervals = {{2, 6}, {7, 9}};
//        int[] newInterval = {15, 18}; // [[2,6],[7,9],[15,18]]


//        int[][] intervals = {{0,1}, {2,6},{9,11}};
//        int[] newInterval = {5,10}; // [[0,1],[2,11]]

        int[][] list = daily.insert(intervals, newInterval);
        for (int[] ints : list) {
            log(ints);
        }
    }

    @Test
    public void lengthOfLastWord() {
        Daily daily = new Daily();

        String[] s = {
                "Hello World", // 5
                "   fly me   to   the moon  ", // 4
                "luffy is still joyboy", // 6
        };
        for (String str : s) {
            int count = daily.lengthOfLastWord(str);
            log("str = %s, count = %s", str, count);
        }
    }

    @Test
    public void generateMatrix() {
        Daily daily = new Daily();

        int n = 1;
        int[][] matrix = daily.generateMatrix(n);
        log(Arrays.deepToString(matrix));
    }


    @Test
    public void uniquePathsWithObstacles() {
        Daily daily = new Daily();

        LinkedList<int[][]> list = new LinkedList<>();
        list.add(new int[][]{{0, 0, 0}, {0, 1, 0}, {0, 0, 0}}); // 2
        list.add(new int[][]{{0, 1}, {0, 0}}); // 1
        list.add(new int[][]{{1, 0}}); // 0
        list.add(new int[][]{{0, 0}, {0, 1}}); // 0
        list.add(new int[][]{{0}}); // 1
        list.add(new int[][]{{1, 0}, {0, 0}}); // 0
        for (int[][] obstacleGrid : list) {
            int count = daily.uniquePathsWithObstacles(obstacleGrid);
            log("count = " + count);
        }

    }

    @Test
    public void minPathSum() {
        Daily daily = new Daily();

        int[][] grid = new int[][]{{1, 3, 1}, {1, 5, 1}, {4, 2, 1}}; // 7
//        int[][] grid = new int[][]{{1, 2, 3}, {4, 5, 6}}; // 12
        int i = daily.minPathSum(grid);
        log("i=" + i);
    }

    @Test
    public void addBinary() {
        Daily daily = new Daily();

//        String a = "11";
//        String b = "1";

        String a = "1010";
        String b = "1011";
        String s = daily.addBinary(a, b);
        log("s = " + s);
    }

    private void log(int[] arr) {
        if (arr.length > 100) {
            int[] shorter = new int[100];
            System.arraycopy(arr, 0, shorter, 0, 100);
            arr = shorter;
        }
        log(Arrays.toString(arr));
    }

    private void log(LinkedList<Integer> list) {
        int count = Math.min(100, list.size());

        StringBuilder sb = new StringBuilder();
        sb.append("[");
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            Integer next = iterator.next();
            sb.append(next);
            count--;
            if (count <= 0) break;
            if (iterator.hasNext()) {
                sb.append(", ");
            }
        }
        sb.append("]");
        log(sb.toString());
    }

    private void log(String msg, Object... args) {
        String format = String.format(msg, args);
        System.out.println(format);
    }

    private long calc(Runnable runnable) {
        long startMs = System.currentTimeMillis();
        runnable.run();
        return System.currentTimeMillis() - startMs;
    }
}